<template>
  <div class="containers">
    <div class="buttons">
      <el-button-group>
        <el-upload action class="upload-demo" :before-upload="openBpmn">
          <el-button icon="el-icon-folder-opened">打开BPMN文件</el-button>
        </el-upload>
        <el-button class="iconfont icon-daohang1" @click="publish">
          发布流程
        </el-button>
        <el-button icon="el-icon-download" @click="downloadBpmn">导出BPMN格式</el-button>
        <el-button icon="el-icon-download" @click="downloadSvg">导出SVG格式</el-button>
      </el-button-group>
    </div>
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
  </div>
</template>
<script>
// 引入Bpmn相关的依赖
import BpmnModeler from "bpmn-js/lib/Modeler";
// 这里引入的是右侧属性栏这个框
import propertiesPanelModule from "bpmn-js-properties-panel";
// 而这个引入的是右侧属性栏里的内容
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
// 右侧属性栏扩展，不然报错
import camundaModdleDescriptor from "camunda-bpmn-moddle/resources/camunda";
// 汉化组件
import customTranslate from "./customTranslate/customTranslate";
var customTranslateModule = {
  translate: ["value", customTranslate],
};
export default {
  props: {
    //初始化使用的bpmn文件
    defaultXmlStr: {
      type: String,
      required: true,
    },
    //调用类型,默认是新增
    callType:{
      type:String,
      required: true,
      default: "add"
    },
    //流程实例ID(修改菜需要)
    audit:{
      type:Object,
      required:false
    }
  },
  mounted() {
    this.init();
  },
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
      xmlStr: "",
    };
  },
  // 方法集合
  methods: {
    async init() {
      this.xmlStr = await this.getXmlUrl();
      this.$nextTick(() => {
        this.initBpmn();
      });
    },
    getXmlUrl() {
      return new Promise((resolve) => {
        setTimeout(() => {
          // const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/mock1.bpmn'
          const url = "";
          resolve(url);
        }, 1000);
      });
    },
    initBpmn() {
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas;
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        //添加左侧控制板
        propertiesPanel: {
          parent: "#js-properties-panel",
        },
        additionalModules: [
          //添加右侧属性面板
          propertiesProviderModule,
          propertiesPanelModule,
          //汉化
          customTranslateModule,
        ],
        moddleExtensions: {
          //如果要在属性面板中修改属性，必须添加
          camunda: camundaModdleDescriptor,
        },
      });
      this.createDiagram();
    },
    //创建BPMN画板
    async createDiagram() {
      if (this.xmlStr === "") {
        this.xmlStr = this.defaultXmlStr;
      }
      try {
        const result = await this.bpmnModeler.importXML(this.xmlStr);
        const { warnings } = result;
      } catch (err) {
        console.log(err.message, err.warnings);
      }
      // 让图能自适应屏幕
      var canvas = this.bpmnModeler.get("canvas");
      canvas.zoom("fit-viewport");
    },
    //导入文件加入NPMN画板
    async createNewDiagram(bpmn) {
      // 将字符串转换成图显示出来;
      this.bpmnModeler.importXML(bpmn, err => {
        if (err) {
          this.$message.error("打开模型出错,请确认该模型符合Bpmn2.0规范");
        }
      });
    },
    //下载NPMN画板内容为NPMN文件文件
    async downloadBpmn() {
      try {
        const result = await this.bpmnModeler.saveXML({
          format: true,
        });
        const { xml } = result;
        const originFilename = this.getFilename(xml);
        const filename = `${originFilename}.bpmn`;
        this.download({ name: filename, data: xml });
      } catch (err) {
        console.log("err", err);
      }
    },
    //下载BPMN画板内容为SVG图标
    downloadSvg() {
      this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
        if (!err) {
          const name = `${this.getFilename(xml)}.svg`;
          // 从建模器画布中提取svg图形标签
          let context = "";
          const djsGroupAll = this.$refs.canvas.querySelectorAll(".djs-group");
          for (let item of djsGroupAll) {
            context += item.innerHTML;
          }
          // 获取svg的基本数据，长宽高
          const viewport = this.$refs.canvas
            .querySelector(".viewport")
            .getBBox();
          // 将标签和数据拼接成一个完整正常的svg图形
          const svg = `
            <svg
              xmlns="http://www.w3.org/2000/svg"
              xmlns:xlink="http://www.w3.org/1999/xlink"
              width="${viewport.width}"
              height="${viewport.height}"
              viewBox="${viewport.x} ${viewport.y} ${viewport.width} ${viewport.height}"
              version="1.1"
              >
              ${context}
            </svg>
          `;
          this.download({ name: name, data: svg });
        }
      });
    },
    //打开本地BPMN文件
    openBpmn(file) {
      const reader = new FileReader();
      //读取文件信息,编码格式为UTF-8
      reader.readAsText(file, 'utf-8');
      reader.onload = () => {
        //读取完毕后讲文件内容导入到NPMN画板中
        this.createNewDiagram(reader.result)
      }
      return false;
    },
    //发布流程
    async publish() {
      try {
        const result = await this.bpmnModeler.saveXML({ format: true })
        const { xml } = result;
        const originFilename = this.getFilename(xml);
        const filename = `${originFilename}.bpmn`;
        if(this.callType === 'add'){
          this.$router.push({name:'/audit/auditManager',params:{file:xml,filename:filename,callType:'add'}})
        }else{
          let originAuditProcess = this.audit;
          this.$router.push({name:'/audit/auditManager',params:{file:xml,filename:filename,callType:'update',process:originAuditProcess}})
        }
      } catch (err) {
        console.log("err", err);
      }
    },
    //获取文件名称
    getFilename(xml) {
      let start = xml.indexOf("process");
      let filename = xml.substr(start, xml.indexOf(">"));
      filename = filename.substr(filename.indexOf("id") + 4);
      filename = filename.substr(0, filename.indexOf('"'));
      return filename;
    },

    //下载文件
    download({ name = "diagram.bpmn", data }) {
      if (data) {
        const a = document.createElement("a");
        a.setAttribute(
          "href",
          `data:application/bpmn20-xml;charset=UTF-8,${encodeURIComponent(data)}`
        );
        a.setAttribute('target', '_blank');
        a.setAttribute('dataTrack', `diagram:donload-${name}`);
        a.setAttribute('download', name);
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
      }
    },
  },
};
</script>
<style scoped>
.containers {
  background-color: #ffffff;
  width: 100%;
  height: calc(100vh - 220px);
}

.canvas {
  width: 100%;
  height: 100%;
}

.panel {
  position: absolute;
  right: 20px;
  top: 110px;
  width: 300px;
  height: calc(100vh - 300px);
  overflow-y: scroll;
}



.upload-demo {
  display: inline-block;
}

.iconfont {
  font-size: 14px;
}

.containerBox {
  height: calc(100vh - 220px);
  position: relative;
}

.containers {
  background-size: 20px 20px, 20px 20px, 10px 10px, 10px 10px;
  background-image: linear-gradient(to right, #dfdfdf 1px, transparent 1px),
    linear-gradient(to bottom, #dfdfdf 1px, transparent 1px),
    linear-gradient(to right, #f1f1f1 1px, transparent 1px),
    linear-gradient(to bottom, #f1f1f1 1px, transparent 1px);
  background-position: left -1px top -1px, left -1px top -1px, left -1px top -1px,
    left -1px top -1px;
}

.buttons {
  display: flex;
  justify-content: center;
}
</style>
